from decimal import Decimal

from django.db import transaction
from django.utils import timezone
from django_redis import get_redis_connection
from rest_framework import serializers

from goods.models import SKU
from orders.models import OrderInfo, OrderGoods


class OrderPlaceSerializer(serializers.ModelSerializer):
    count = serializers.IntegerField(min_value=1, label="数量")

    class Meta:
        model = SKU
        fields = ("default_image_url", "name", "price", "count", "id")

class OrderCommitSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ("address", "pay_method", "order_id")

        read_only_fields = ["order_id"]  # 序列化的时候,(也就是返回的时候用,反序列化的时候不用)

        # write_only, 反序列化的时候用, 序列化的时候不用
        extra_kwargs = {
            "address": {
                "write_only": True
            },
            "pay_method": {
                "write_only": True
            }
        }

    # 1,重写create方法,去出redis数据,创建订单对象, 订单商品对象
    @transaction.atomic
    def create(self, validated_data):

        # 1,获取user
        user = self.context["request"].user

        # 2,创建订单编号(尽量保证唯一性)
        order_id = timezone.now().strftime("%Y%m%d%H%M%S") + "%06d" % user.id

        # 3,获取地址
        address = validated_data["address"]

        # 4,获取支付方式
        pay_method = validated_data["pay_method"]

        # 5,订单状态
        if pay_method == OrderInfo.PAY_METHODS_ENUM["CASH"]:
            status = OrderInfo.ORDER_STATUS_ENUM["UNPAID"]
        else:
            status = OrderInfo.ORDER_STATUS_ENUM["UNSEND"]

        #TODO  设置保存点
        sid = transaction.savepoint()
        # 6,创建订单信息对象
        order = OrderInfo.objects.create(
            order_id=order_id,
            user=user,
            address=address,
            total_count=0,
            total_amount=Decimal(0.0),
            freight=Decimal(10.0),
            pay_method=pay_method,
            status=status,
        )

        # 7,获取redis中数据
        redis_conn = get_redis_connection("cart")
        cart_dict = redis_conn.hgetall("cart_%s" % user.id)
        cart_selected_list = redis_conn.smembers("cart_selected_%s" % user.id)

        # 8,遍历创建订单商品对象
        for sku_id in cart_selected_list:
            # 8.1获取商品对象,数量
            sku = SKU.objects.get(id=sku_id)
            count = int(cart_dict[sku_id])

            # 8.2判断库存量是否足够
            if count > sku.stock:
                #TODO 回滚
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError("库存不足")

            #TODO
            import time
            time.sleep(5)

            # # 8.3减少库存,增加销量
            # sku.stock -= count
            # sku.sales += count
            # sku.save()

            # TODO 使用乐观锁，解决并发下单问题
            old_stock = sku.stock
            old_sales = sku.sales
            new_stock = old_stock - count
            new_sales = old_sales + count

            ret = SKU.objects.filter(id=sku_id,stock=old_stock).update(stock=new_stock,sales=new_sales)

            if ret == 0:
                # raise serializers.ValidationError("下单失败")
                continue
            # 8.4累加商品数量和价格
            order.total_count += count
            order.total_amount += (sku.price * count)

            # 8.5创建订单商品对象
            OrderGoods.objects.create(
                order=order,
                sku=sku,
                count=count,
                price=sku.price,
            )
            break
        # 9,保存,清除redis数据
        order.save()
        transaction.savepoint_commit(sid) #TODO 提交
        redis_conn.hdel("cart_%s" % user.id, *cart_selected_list)
        redis_conn.srem("cart_selected_%s" % user.id, *cart_selected_list)

        # 10,返回响应
        return order

